/***************************************************************************************************
 * brief:     feature support , osd display picture 
 * detail:    big file read, decode file and fix the window 
 *            size, and give the examle
 * author:    saicheong.yuen
 * date:      2014-7-14
 ***************************************************************************************************/

#include <sys_config.h>

#ifdef PIP_PNG_GIF

#include <basic_types.h>
#include <mediatypes.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <hld/hld_dev.h>
#include <hld/ge/ge.h>
#include <hld/osd/osddrv_dev.h>
#include <hld/dis/vpo.h>
#include <api/libfs2/stdio.h>

#include <api/libimagedec/imagedec.h>
#include <api/libmp/gif.h>
#include <api/libmp/png.h>
#include <hld/osd/osddrv.h>

/* "ad_pic_conf.h" must be front, such as here, follow ad_pic_*.h */
#include "ad_pic_conf.h"

#include "ad_pic_file.h"
#include "ad_pic_src.h"
#include "win_com_popup.h"

#ifndef NEW_DEMO_FRAME
#include <api/libpub29/lib_hde.h>
#else
#include <api/libpub/lib_frontend.h>
#include <api/libpub/lib_hde.h>
#endif
#include <api/libchunk/chunk.h>


#ifdef  AD_PIC_DEBUG
#define AD_PIC_PRINTF	libc_printf
#else
#define AD_PIC_PRINTF(...)	do{}while(0)
#endif

/***************************************************************************************************
 * brief:     jpg/bmp file decoder operation
 * detail:    methods:
 *            1. ad_pic_jpgbmp_draw
 *            2. ad_pic_jpgbmp_decode
 *            3. ad_pic_jpgbmp_close
 *            4. ad_pic_jpgbmp_ge_display
 *            5. ad_pic_jpgbmp_ge_undisplay
 *            6. ad_pic_jpgbmp_osdlayer1_display
 *            7. ad_pic_jpgbmp_osdlayer1_display
 * author:    saicheong.yuen
 * date:      2014-9-26
 *            2014-11-14 
 ***************************************************************************************************/

/* low osd callback function, just update the picture rectangle area. */
static void ad_pic_jpgbmp_update_cb(void *handle, pImagedec_Out_Image pimage, struct Rect *rect)
{
    struct Rect *dst_rect;
    dst_rect = (struct Rect*) handle;
    dst_rect->uStartX = rect->uStartX;
    dst_rect->uStartY = rect->uStartY;
    dst_rect->uWidth  = rect->uWidth;
    dst_rect->uHeight = rect->uHeight;	
}

/* decode the jpeg bmp file and buffer it. */
static int ad_pic_jpgbmp_decode(file_h fh, UINT8 *deccode_buf, INT32 deccode_buflen, UINT8 *bitmap_buf, INT32 bitmap_buflen, struct Rect *src_rect, struct Rect *dst_rect)
{
    BOOL    ret = 0;
    INT32   bitmap_pic_len = 0;

    if ((NULL == deccode_buf) || (NULL == bitmap_buf) || (NULL == src_rect) || (NULL == dst_rect))
    {
        AD_PIC_PRINTF("%s() pointer parameter is NULL!\n", __FUNCTION__);
        return RET_FAILURE;
    }

    UINT32 chip_id   = 0;
    INT32  bytedepth = 4;
    chip_id = sys_ic_get_chip_id();
    if (ALI_S3281 == chip_id)
    {
        bytedepth = 2;
    }

    bitmap_pic_len = (INT32)((INT32)src_rect->uWidth * (INT32)src_rect->uHeight) * 4;
    if (bitmap_buflen < bitmap_pic_len)
    {
        AD_PIC_PRINTF("%s() buffer size if too small, may lead to problem!\n", __FUNCTION__);
        return RET_FAILURE;
    }

    imagedec_id id = 0;

    /* initialize the decode buffer, and image file operations */
    Imagedec_Init_Config img_init_info;
    MEMSET(&img_init_info,0,sizeof(Imagedec_Init_Config));
    img_init_info.decoder_buf = deccode_buf;
    img_init_info.decoder_buf_len = deccode_buflen;
    img_init_info.fread_callback = ad_pic_file_read;
    img_init_info.fseek_callback = ad_pic_file_seek;

    id = imagedec_init(&img_init_info);
    AD_PIC_PRINTF("%s() imagedec_init id = (%d)!\n", __FUNCTION__, id);
    if (0 == id)
    {
        AD_PIC_PRINTF("%s() imagedec_init failed(%d)!\n", __FUNCTION__, id);
        return RET_FAILURE;
    }

    /* configure the decoder. */
#ifdef DUAL_ENABLE
    ret = imagedec_ioctl_ex(id, IMAGEDEC_IO_CMD_OPEN_HW_ACCE, 0);
#else
    ret = imagedec_ioctl(id, IMAGEDEC_IO_CMD_OPEN_HW_ACCE, 0);
#endif
    if (TRUE != ret)
    {
        AD_PIC_PRINTF("%s() imagedec_ioctl(IMAGEDEC_IO_CMD_OPEN_HW_ACCE) failed!\n", __FUNCTION__);
        return RET_FAILURE;
    }

    /* configure the decode system. */
    Imagedec_Mode_Par dec_par;
    MEMSET((void *)&dec_par,0,sizeof(Imagedec_Mode_Par));
    dec_par.vp_close_control = 0;
    dec_par.pro_show = 1;
    dec_par.dis_rect.uStartX = 0;
    dec_par.dis_rect.uStartY = 0;
    dec_par.dis_rect.uWidth = 720;
    dec_par.dis_rect.uHeight = 576;
    dec_par.src_rect.uStartX = 0;
    dec_par.src_rect.uStartY = 0;
    dec_par.src_rect.uWidth = 720;
    dec_par.src_rect.uHeight = 576;
    imagedec_set_mode(id, 1, &dec_par);

    /* configure the osd callback and output parameters. */
    Imagedec_Osd_Config config;
    MEMSET((void *)&config, 0, sizeof(Imagedec_Osd_Config));
    config.blt = ad_pic_jpgbmp_update_cb;
    config.handle = ((void*)dst_rect);
    config.pic_frmt = 0;
    imagedec_osd_init(&config);


    /* configure the osd input parameters and buffer. */
    Imagedec_Osd_Io_Cmd cmd;
    MEMSET((void *)&cmd,0,sizeof(Imagedec_Osd_Io_Cmd));
    cmd.on = 1;
    cmd.bitmap_start = (UINT32)bitmap_buf;
    cmd.bitmap_size = bitmap_buflen;
    cmd.dis_rect.uStartX = src_rect->uStartX;
    cmd.dis_rect.uStartY = src_rect->uStartY;
    cmd.dis_rect.uWidth  = src_rect->uWidth;
    cmd.dis_rect.uHeight = src_rect->uHeight;
#ifdef DUAL_ENABLE
    imagedec_ioctl_ex(id, IMAGEDEC_IO_CMD_OSD_SHOW, (UINT32)&cmd);
#else
    imagedec_ioctl(id, IMAGEDEC_IO_CMD_OSD_SHOW, (UINT32)&cmd);
#endif

    /* decode. */
    ret = imagedec_decode(id, fh);
    if (ret != TRUE)
        AD_PIC_PRINTF("Decode Image Unsuccessfully\n");

#ifdef DUAL_ENABLE
        imagedec_ioctl_ex(id, IMAGEDEC_IO_CMD_OSD_SHOW, (UINT32)NULL);
#else
        imagedec_ioctl(id, IMAGEDEC_IO_CMD_OSD_SHOW, (UINT32)NULL);
#endif


    /* recycle the resouce. */
    if (imagedec_stop(id) != TRUE)
        AD_PIC_PRINTF("\n Stop Image decoding unsuccessfully!\n");
    if (imagedec_release(id) != TRUE)
        AD_PIC_PRINTF("\n Release Image decoder unsuccessfully!\n");   

    /* return. */
    if (ret != TRUE)
        return RET_FAILURE;
    else
        return RET_SUCCESS;
}

/* release the source */
static int ad_pic_jpgbmp_close()
{
    return RET_SUCCESS;
}

/* display the image stored in the buffer. */
static int ad_pic_jpgbmp_ge_display(UINT8 *buf, struct OSDRect *rect, UINT16 pixel_pitch)
{
    ge_rect_t dst_rect, src_rect;
    struct ge_device *ge_dev;
    INT32 ret;
    ge_operating_entity entity;
    UINT32 layer_id = 0;
    UINT32 region_id =0;
    UINT32 cmd_hdl = 0;

    if (buf == NULL)
    {
        AD_PIC_PRINTF("%s() para buf illegal!\n", __FUNCTION__);
        return RET_FAILURE;
    }

    ge_dev = (struct ge_device *)dev_get_by_id(HLD_DEV_TYPE_GE, 0);
    ge_cmd_list_hdl cmd_list = ge_cmd_list_create(ge_dev, 10);
    if (ge_dev == NULL)
    {
        AD_PIC_PRINTF("%s() ge device find failed!\n", __FUNCTION__);
        return RET_FAILURE;
    }
    
    src_rect.left = rect->uLeft;
    src_rect.top = rect->uTop;
    src_rect.width = rect->uWidth;
    src_rect.height = rect->uHeight;
    
	//set image show location
	dst_rect.left = rect->uLeft;
    dst_rect.top = rect->uTop;
    dst_rect.width = rect->uWidth;
    dst_rect.height = rect->uHeight;
    AD_PIC_PRINTF("left: %d, top: %d, width: %d, height: %d\n", dst_rect.left, dst_rect.top,
        dst_rect.width, dst_rect.height);

    osal_cache_flush(buf, src_rect.width * src_rect.height * 4 );
    ge_cmd_list_new(ge_dev,cmd_list,GE_COMPILE_AND_EXECUTE);
    ge_gma_set_region_to_cmd_list(ge_dev,layer_id,region_id,cmd_list);

    entity.color_format = GE_PF_ARGB8888;
    entity.base_address = (UINT8 *)buf;
    entity.data_decoder = GE_DECODER_DISABLE;
    entity.pixel_pitch = src_rect.width;
    entity.modify_flags = GE_BA_FLAG_ADDR|GE_BA_FLAG_FORMAT|GE_BA_FLAG_PITCH;

    cmd_hdl = ge_cmd_begin(ge_dev,cmd_list,GE_DRAW_BITMAP);             
    ge_set_operating_entity(ge_dev,cmd_hdl,GE_PTN,&entity); 
    ge_set_clut_rgb_order(ge_dev,cmd_hdl,GE_RGB_ORDER_ARGB);
    ge_set_xy(ge_dev,cmd_hdl,GE_DST,dst_rect.left,dst_rect.top);
    ge_set_xy(ge_dev,cmd_hdl,GE_SRC,dst_rect.left,dst_rect.top);
    ge_set_xy(ge_dev,cmd_hdl,GE_PTN,src_rect.left,src_rect.top);                
    ge_set_wh(ge_dev,cmd_hdl,GE_DST_PTN,dst_rect.width,dst_rect.height);

    ge_cmd_end(ge_dev,cmd_hdl);
    return ret;
}

static int ad_pic_jpgbmp_ge_undisplay()
{
    OSD_ClearScreen();

    return RET_SUCCESS;
}

/***************************************************************************************************
 * brief:     gif file decoder operation
 * detail:    methods:
 *            1. ad_pic_gif_draw
 *            2. ad_pic_gif_decode
 *            3. ad_pic_gif_close
 *            4. ad_pic_gif_ge_display
 *            5. ad_pic_gif_ge_undisplay
 * author:    saicheong.yuen
 * date:      2014-9-26
 ***************************************************************************************************/

static struct gif_instance *gif = NULL;

/* decode the gif file and display it. */
static int ad_pic_gif_decode(file_h fh, UINT8 *deccode_buf, INT32 deccode_buflen, UINT8 *bitmap_buf, INT32 bitmap_buflen, struct Rect *src_rect, struct Rect *dst_rect)
{
	struct gif_cfg init;
	MEMSET((void *)&init,0,sizeof(struct gif_cfg));

    init.bit_buf_size  = 0x80000;
    init.bit_buf_start = deccode_buf;
    init.dec_buf_start = init.bit_buf_start + init.bit_buf_size;
    init.dec_buf_size  = deccode_buflen - init.bit_buf_size - 0x10000;

	init.fread_callback = ad_pic_file_read;
	init.fseek_callback = ad_pic_file_seek;
	init.ftell_callback = ad_pic_file_tell;
	init.max_width = 1280;//800;
	init.max_height = 720;//600;

    src_rect->uWidth = 1280;
    src_rect->uHeight = 720;

    gif_init(&init);
    gif = gif_open();
    if (gif == NULL)
    {
        AD_PIC_PRINTF("%s: gif instance is NULL!\n", __FUNCTION__);
        return RET_FAILURE;
    }

    if (1)
        gif_io_ctrl(gif, GIF_IO_CMD_DEC_FIRST_PIC, GIF_FALSE);
    else
        gif_io_ctrl(gif, GIF_IO_CMD_DEC_FIRST_PIC, GIF_TRUE);

    struct ge_device* ge_dev;
    ge_dev = (struct ge_device *)dev_get_by_id(HLD_DEV_TYPE_GE, 0);
    if (ge_dev == NULL)
    {
        AD_PIC_PRINTF("%s() ge device find failed!\n", __FUNCTION__);
        return RET_FAILURE;
    }

    struct OSDRect rect;
    rect.uLeft=src_rect->uStartX;
    rect.uTop=src_rect->uStartY;
    rect.uWidth=src_rect->uWidth;
    rect.uHeight=src_rect->uHeight;

    struct gif_dec_par par;
    MEMSET((void *)&par, 0, sizeof(struct gif_dec_par));
    par.in_par.file = fh;
    par.in_par.fread_callback = ad_pic_file_read;
    par.in_par.fseek_callback = ad_pic_file_seek;
    par.in_par.ftell_callback = ad_pic_file_tell;

    par.out_par.dev = (gif_ge_dev)ge_dev;
    par.out_par.handle = 0;//(gif_surface_handle)ad_pic_get_ge_surface(AD_DST_SURFACE);
    par.out_par.region = 0;
    par.out_par.pos.x = rect.uLeft;
    par.out_par.pos.y = 0; //rect->uTop; //for the region
    par.out_par.area.x = 0;
    par.out_par.area.y = 0;
    par.out_par.area.w = rect.uWidth;
    par.out_par.area.h = rect.uHeight;

    gif_dec(gif, &par);

    return RET_SUCCESS;
}

/* release the source */
static int ad_pic_gif_close()
{
    if (NULL != gif)
    {
        gif_file fh;
        fh = 1;
        gif_stop(gif, 1);
    
        gif_close(gif);
        gif = NULL;
    }
    return RET_SUCCESS;
}

/* resersed */
static int ad_pic_gif_ge_display(UINT8 *buf, struct OSDRect *rect, UINT16 pixel_pitch)
{
    return RET_SUCCESS;
}

/* resersed */
static int ad_pic_gif_ge_undisplay()
{
    OSD_ClearScreen();

    return RET_SUCCESS;
}

/***************************************************************************************************
 * brief:     png file decoder operation
 * detail:    methods:
 *            1. ad_pic_png_draw
 *            2. ad_pic_png_decode
 *            3. ad_pic_png_close
 *            4. ad_pic_png_ge_display
 *            5. ad_pic_png_ge_undisplay
 * author:    saicheong.yuen
 * date:      2014-9-26
 ***************************************************************************************************/

static struct png_instance *png = NULL;
static struct png_image img;

#define PNG_BIT_SIZE		(64*1024)//0x8000

static int ad_pic_png_draw(struct png_image *img, struct png_view_par *par)
{
    ge_rect_t dst_rect, src_rect;
    struct ge_device *ge_dev;
    INT32 ret;
    ge_operating_entity entity;
    UINT32 layer_id = 0;
    UINT32 region_id =0;
    UINT32 cmd_hdl = 0;


    ge_dev = (struct ge_device *)dev_get_by_id(HLD_DEV_TYPE_GE, 0);
    ge_cmd_list_hdl cmd_list = ge_cmd_list_create(ge_dev, 10);
    if (ge_dev == NULL)
    {
        AD_PIC_PRINTF("%s() ge device find failed!\n", __FUNCTION__);
        return RET_FAILURE;
    }
    
    src_rect.left = 0;
    src_rect.top = 0;

    src_rect.width = img->size.w;//img->hw_stride;//img->hw_stride;
    src_rect.height = img->size.h;//img->hw_y_stride;//img->hw_y_stride;
    entity.pixel_pitch = src_rect.width;//src_rect.width;


    AD_PIC_PRINTF("%s(): png decode img is NULL! buf=%p wid=%d heig=%d\n", __FUNCTION__, 
        img->graphic_buf, src_rect.width, src_rect.height);


	dst_rect.left = par->pos.x;
	dst_rect.top = par->pos.y;
	dst_rect.width = src_rect.width;
	dst_rect.height = src_rect.height;

    osal_cache_flush(img->graphic_buf, src_rect.width * src_rect.height * 4 );
    ge_cmd_list_new(ge_dev,cmd_list,GE_COMPILE_AND_EXECUTE);
    ge_gma_set_region_to_cmd_list(ge_dev,layer_id,region_id,cmd_list);

    entity.color_format = GE_PF_ARGB8888;
    entity.base_address = (UINT8 *)img->graphic_buf;
    entity.data_decoder = GE_DECODER_DISABLE;
    entity.modify_flags = GE_BA_FLAG_ADDR|GE_BA_FLAG_FORMAT|GE_BA_FLAG_PITCH;

    cmd_hdl = ge_cmd_begin(ge_dev,cmd_list,GE_DRAW_BITMAP);             
    ge_set_operating_entity(ge_dev,cmd_hdl,GE_PTN,&entity); 
    ge_set_clut_rgb_order(ge_dev,cmd_hdl,GE_RGB_ORDER_ARGB);
    ge_set_xy(ge_dev,cmd_hdl,GE_DST,dst_rect.left,dst_rect.top);
    ge_set_xy(ge_dev,cmd_hdl,GE_SRC,dst_rect.left,dst_rect.top);
    ge_set_xy(ge_dev,cmd_hdl,GE_PTN,src_rect.left,src_rect.top);                
    ge_set_wh(ge_dev,cmd_hdl,GE_DST_PTN,dst_rect.width,dst_rect.height);

    ge_cmd_end(ge_dev,cmd_hdl);
    return ret;
 }

/* decode the gif file and display it. */
static int ad_pic_png_decode(file_h fh, UINT8 *deccode_buf, INT32 deccode_buflen, UINT8 *bitmap_buf, INT32 bitmap_buflen, struct Rect *src_rect, struct Rect *dst_rect)
{
    struct png_cfg cfg;
	MEMSET((void *)&cfg,0,sizeof(struct png_cfg));
    PNG_RET ret = PNG_FALSE;

    cfg.bit_buf_size = PNG_BIT_SIZE;
    cfg.bit_buf_start = deccode_buf;
    cfg.dec_buf_start = cfg.bit_buf_start + cfg.bit_buf_size;
    cfg.dec_buf_size  = deccode_buflen - cfg.bit_buf_size - 0x10000;


    //cfg.dec_buf = cfg.dec_buf_start;
    //cfg.dec_buf_totalsize = cfg.dec_buf_size;
    png = png_open(&cfg);
    if (png == NULL)
    {
        AD_PIC_PRINTF("%s: png instance is NULL!\n", __FUNCTION__);
        return RET_FAILURE;
    }

    struct png_file file;
    MEMSET((void *)&file, 0, sizeof(struct png_file));
    file.handle = fh;
    file.fread = ad_pic_file_read;
    file.fseek = ad_pic_file_seek;
    file.ftell = ad_pic_file_tell;


    MEMSET((void *)&img, 0, sizeof(struct png_image));
#ifdef PNG_OUT_CLUT8_PIC
    img.cf_defined = PNG_CF_DEFINED_AUTOMATICALLY;
#else
    img.cf_defined = PNG_CF_DEFINED_MANUALLY;
#endif
    img.plt_type = PNG_PLT_AYCBCR8888;

    ret = png_dec(png, &file, &img, PNG_SYNC);  //the synchronous mode
    if (ret != PNG_TRUE)
    {
        if (NULL != png)
        {
            png_close(png);
            png = NULL;
        }
        return RET_FAILURE;
    }

    if (NULL == img.graphic_buf)
    {
        AD_PIC_PRINTF("%s: png image is NULL!\n", __FUNCTION__);
        if (NULL != png)
        {
            png_close(png);
            png = NULL;
        }
        return RET_FAILURE;
    }

    return RET_SUCCESS;
}

/* release the source */
static int ad_pic_png_close()
{
    if (NULL != png)
    {
        png_stop(png);
        
        png_close(png);
        png = NULL;
    }

    return RET_SUCCESS;
}

/* resersed */
static int ad_pic_png_ge_display(UINT8 *buf, struct OSDRect *rect, UINT16 pixel_pitch)
{
    AD_PIC_PRINTF("%s() : decoder PNG display!\n", __FUNCTION__);

    struct png_view_par view_par;
    MEMSET((void *)&view_par, 0, sizeof(struct png_view_par));
    view_par.handle0 = 0;
    view_par.pos.x = 0;//70;//rect->uLeft;
    view_par.pos.y = 0;//10;//0;  //rect->uTop;
    png_view(png, &img, &view_par, ad_pic_png_draw);


    return RET_SUCCESS;
}

/* resersed */
static int ad_pic_png_ge_undisplay()
{
    OSD_ClearScreen();

    return RET_SUCCESS;
}

typedef struct ad_pic_decoder_s { 
    int (*decode) (file_h fh, UINT8 *deccode_buf, INT32 deccode_buflen, UINT8 *bitmap_buf, INT32 bitmap_buflen, struct Rect *src_rect, struct Rect *dst_rect);
    int (*close)();
    int (*display)(UINT8 *buf, struct OSDRect *rect, UINT16 pixel_pitch);
    int (*undisplay)();
} ad_pic_decoder_t;

ad_pic_decoder_t ad_pic_jpgbmp_decoder = 
{
    ad_pic_jpgbmp_decode,
    ad_pic_jpgbmp_close,
    ad_pic_jpgbmp_ge_display,
    ad_pic_jpgbmp_ge_undisplay
};

ad_pic_decoder_t ad_pic_gif_decoder = 
{
    ad_pic_gif_decode,
    ad_pic_gif_close,
    ad_pic_gif_ge_display,
    ad_pic_gif_ge_undisplay
};

ad_pic_decoder_t ad_pic_png_decoder = 
{
    ad_pic_png_decode,
    ad_pic_png_close,
    ad_pic_png_ge_display,
    ad_pic_png_ge_undisplay
};

ad_pic_decoder_t *ad_pic_decoder;

static int app_ad_pic_getdecoder(char *filename)
{
	char *ext;
	ext = strrchr(filename, '.');
	if (ext)
	{
		if((!strncasecmp(ext, ".png", 4)) || (!strncasecmp(ext, ".PNG", 4)))
		{  
		    ad_pic_decoder = &ad_pic_png_decoder;
            AD_PIC_PRINTF("selet the png decoder!\n");
			return RET_SUCCESS;
		}
		if((!strncasecmp(ext, ".gif", 4)) || (!strncasecmp(ext, ".GIF", 4)))
		{       
		    ad_pic_decoder = &ad_pic_gif_decoder;
            AD_PIC_PRINTF("selet the gif decoder!\n");
			return RET_SUCCESS;
		}
        if((!strncasecmp(ext, ".jpg", 4)) || (!strncasecmp(ext, ".JPG", 4)))
        {         
            ad_pic_decoder = &ad_pic_jpgbmp_decoder;
            AD_PIC_PRINTF("selet the jpg decoder!\n");
            return RET_SUCCESS;;
        }
        if((!strncasecmp(ext, ".jpeg", 5)) || (!strncasecmp(ext, ".JPEG", 5)))
        {
            ad_pic_decoder = &ad_pic_jpgbmp_decoder;
            AD_PIC_PRINTF("selet the jpeg decoder!\n");
            return RET_SUCCESS;
        }
        if((!strncasecmp(ext, ".bmp", 4)) || (!strncasecmp(ext, ".bmp", 4)))
        {
            ad_pic_decoder = &ad_pic_jpgbmp_decoder;
            AD_PIC_PRINTF("selet the bmp decoder!\n");
            return RET_SUCCESS;
        }
	}
    return RET_FAILURE;
}

#define AP_PIC_FOP_METHOD_NONE      0
#define AP_PIC_FOP_METHOD_PECACHE   1
#define AP_PIC_FOP_METHOD_MEM       2
#define AP_PIC_FOP_METHOD_BUFF      3

#define AP_PIC_DEC_METHOD_NONE      0
#define AP_PIC_DEC_METHOD_JPGBMP    1
#define AP_PIC_DEC_METHOD_GIF       2
#define AP_PIC_DEC_METHOD_PNG       3


static int app_ad_pic_getdecodertype(char *filename, BOOL usbfile, int* p_dec_type, int* p_fop_type)
{
    int dec_type = AP_PIC_DEC_METHOD_NONE;
    int fop_type = AP_PIC_FOP_METHOD_NONE;
	char *ext;
	ext = strrchr(filename, '.');
	if (ext)
	{
		if((!strncasecmp(ext, ".png", 4)) || (!strncasecmp(ext, ".PNG", 4)))
		{  
             dec_type = AP_PIC_DEC_METHOD_PNG;
             fop_type = AP_PIC_FOP_METHOD_MEM;
		}
		if((!strncasecmp(ext, ".gif", 4)) || (!strncasecmp(ext, ".GIF", 4)))
		{       
		    dec_type = AP_PIC_DEC_METHOD_GIF;
            fop_type = AP_PIC_FOP_METHOD_MEM;
		}
        if((!strncasecmp(ext, ".jpg", 4)) || (!strncasecmp(ext, ".JPG", 4)))
        {         
            dec_type = AP_PIC_DEC_METHOD_JPGBMP;
            fop_type = AP_PIC_FOP_METHOD_PECACHE;
        }
        if((!strncasecmp(ext, ".jpeg", 5)) || (!strncasecmp(ext, ".JPEG", 5)))
        {
            dec_type = AP_PIC_DEC_METHOD_JPGBMP;
            fop_type = AP_PIC_FOP_METHOD_PECACHE;
        }
        if((!strncasecmp(ext, ".bmp", 4)) || (!strncasecmp(ext, ".bmp", 4)))
        {
            dec_type = AP_PIC_DEC_METHOD_JPGBMP;
            fop_type = AP_PIC_FOP_METHOD_PECACHE;
        }
        if (dec_type == AP_PIC_DEC_METHOD_NONE)
        {
            fop_type = AP_PIC_FOP_METHOD_NONE;
            return RET_FAILURE;
        }
	}

#ifndef ENABLE_PE_CACHE
    fop_type = AP_PIC_FOP_METHOD_MEM;
#endif
    if (usbfile == FALSE)
    {
        fop_type = AP_PIC_FOP_METHOD_BUFF;
    }

    *p_dec_type = dec_type;
    *p_fop_type = fop_type;

    return RET_SUCCESS;
}



/***************************************************************************************************
 * brief:     the example to use api to show pic.
 * detail:    the example to use api to show pic.
 * author:    saicheong.yuen
 * date:      2014-9-26
 ***************************************************************************************************/
 
typedef struct app_ad_pic_data_s
{
    file_h         hdl_curr;
    UINT8          *deccode_buf;
    INT32          deccode_buflen;
    UINT8          *bitmap_buf;
    INT32          bitmap_buflen;
    struct Rect    src_rect;
    struct Rect    dst_rect;    
} app_ad_pic_data_t;

/* allocation resouce and configure. decode the image file and buffer it. */
static int app_ad_pic_decode(app_ad_pic_data_t *ppic_img_data, const char* file_name)
{
    int         ret = RET_SUCCESS;
    UINT8       *decode_buf = NULL;
    INT32       deccode_buflen = 0;
    UINT8       *picture_buf = NULL;
    INT32       picture_buflen = 0;
    UINT8       *fileoper_buf = NULL;
    INT32       fileoper_buflen = 0;
    BOOL        usbfile_filled = TRUE;


    ad_pic_bufmgr_init();

    ad_pic_dbase_getimg_byname(file_name, &fileoper_buf, &fileoper_buflen);
    if (fileoper_buf != NULL)
    {
        ret = ad_pic_bufffile_init(&(ppic_img_data->hdl_curr), fileoper_buf, fileoper_buflen);
        if (ret != RET_SUCCESS)
        {
             AD_PIC_PRINTF("%s: (buf)file can't be opened!\n", __FUNCTION__);
            return RET_FAILURE;
        }
        usbfile_filled = FALSE;
    }


#if (SYS_SDRAM_SIZE == 64)
    int dec_type = AP_PIC_DEC_METHOD_NONE;
    int fop_type = AP_PIC_FOP_METHOD_NONE;

    ret = app_ad_pic_getdecodertype(file_name, usbfile_filled, &dec_type, &fop_type);
    if (RET_SUCCESS != ret)
    {
        AD_PIC_PRINTF("%s: decoder and fileoper can't be found!\n", __FUNCTION__);
        return RET_FAILURE;  
    }

    ret = ad_pic_bufmgr_adjust(dec_type, fop_type);
    if (RET_SUCCESS != ret)
    {
        AD_PIC_PRINTF("%s: adjust buffer failed!\n", __FUNCTION__);
        return RET_FAILURE;  
    }
#endif

    if (usbfile_filled == TRUE)
    {
#if 1
        /* check if the usb inserted */
        if (check_usb_item_is_active() == FALSE)
        {
            AD_PIC_PRINTF("%s() : no usb!\n", __FUNCTION__);
            return RET_FAILURE;
        }
#endif
        /* get the file handle. */
        ret = ad_pic_file_init(&(ppic_img_data->hdl_curr), file_name);
        if (RET_SUCCESS != ret)
        {
            AD_PIC_PRINTF("%s: file can't be opened!\n", __FUNCTION__);
            return RET_FAILURE;  
        }
    }

    ret = app_ad_pic_getdecoder(file_name);
    if (RET_SUCCESS != ret)
    {
        AD_PIC_PRINTF("%s: decoder can't be found!\n", __FUNCTION__);
        return RET_FAILURE;  
    }

    /* configure the picture size and location. define the display area. */
    ppic_img_data->src_rect.uStartX = 0;
    ppic_img_data->src_rect.uStartY = 0;
    ppic_img_data->src_rect.uWidth  = 400;
    ppic_img_data->src_rect.uHeight = 300;

    /* the final picture size will fill dst_rect. fix the display area. */
    MEMSET((void *)&(ppic_img_data->dst_rect), 0, sizeof(struct OSDRect));


    ad_pic_bufmgr_get_decodebuffer(&decode_buf, &deccode_buflen);
    ad_pic_bufmgr_get_picturebuffer(&picture_buf, &picture_buflen);

    /* decode buffer allocation. */
    ppic_img_data->deccode_buf = decode_buf;
    ppic_img_data->deccode_buflen = deccode_buflen;


    /* picture buffer allocation. */
    ppic_img_data->bitmap_buf = picture_buf;
    ppic_img_data->bitmap_buflen= picture_buflen;

    /* decode the image file */
    ret = ad_pic_decoder->decode(ppic_img_data->hdl_curr, ppic_img_data->deccode_buf, ppic_img_data->deccode_buflen, 
                ppic_img_data->bitmap_buf, ppic_img_data->bitmap_buflen, &ppic_img_data->src_rect, &ppic_img_data->dst_rect);
    if (RET_SUCCESS != ret)
    {
        ad_pic_decoder->close();
        if (usbfile_filled == TRUE)
            ad_pic_file_exit(ppic_img_data->hdl_curr);
        AD_PIC_PRINTF("%s: decode image file failured!\n", __FUNCTION__);
        return RET_FAILURE;
    }

    //ad_pic_bufffile_exit(ppic_img_data->hdl_curr);
    if (usbfile_filled == TRUE)
    {
        ret = ad_pic_file_exit(ppic_img_data->hdl_curr);
        if (RET_SUCCESS != ret)
        {
            ad_pic_decoder->close();
            AD_PIC_PRINTF("%s: file close error!\n", __FUNCTION__);
            return RET_FAILURE;
        }
    }

    AD_PIC_PRINTF("%s(): decode finish!\n", __FUNCTION__);

    return RET_SUCCESS;
}


/* display the picture. refer the file_name as the path. */
static int app_ad_pic_display(app_ad_pic_data_t *ppic_img_data)
{
    struct OSDRect draw_rect;
    int    ret = RET_SUCCESS;

    /* draw the picture by using ge */

    draw_rect.uLeft   = ppic_img_data->dst_rect.uStartX;
    draw_rect.uTop    = ppic_img_data->dst_rect.uStartY;
    draw_rect.uWidth  = ppic_img_data->dst_rect.uWidth;
    draw_rect.uHeight = ppic_img_data->dst_rect.uHeight;
    
    ret = ad_pic_decoder->display(ppic_img_data->bitmap_buf, &draw_rect, draw_rect.uWidth);

    return RET_SUCCESS;
}

/* undisplay the picture. and recycle the resouces */
static int app_ad_pic_undisplay(app_ad_pic_data_t *ppic_img_data)
{
    int ret = RET_SUCCESS;

    ret = ad_pic_decoder->close();
    if (ret != RET_SUCCESS)
    {
        AD_PIC_PRINTF("%s() : decoder close failed!\n", __FUNCTION__);
    }

    ret = ad_pic_decoder->undisplay();
    if (ret != RET_SUCCESS)
    {
        AD_PIC_PRINTF("%s() : decoder undisplay failed!\n", __FUNCTION__);
    }

    return ret;
}


/***************************************************************************************************
 * brief:     application, display the picture by using reference path. 
 * detail:    application, display the picture by using reference path. 
 * author:    saicheong.yuen
 * date:      2014-9-26
 ***************************************************************************************************/

#ifdef SUPPORT_DEBUG_USING_OWN_PICTURE
/* image file path */
const char* app_ad_pic_jpg_item[] = {
"/mnt/uda1/jpg/1.JPG",
"/mnt/uda1/jpg/2.JPG",
"/mnt/uda1/jpg/3.JPG",
"/mnt/uda1/jpg/4.JPG",
"/mnt/uda1/jpg/5.JPG"
};

/* image file path */
const char* app_ad_pic_bmp_item[] = {
"/mnt/uda1/bmp/1.BMP",
"/mnt/uda1/bmp/2.BMP",
"/mnt/uda1/bmp/3.BMP",
"/mnt/uda1/bmp/4.BMP",
"/mnt/uda1/bmp/5.BMP"
};

/* image file path */
const char* app_ad_pic_gif_item[] =
{
"img_gif1.gif",
"img_gif2.gif",
"img_gif3.gif",
"img_gif4.gif",
//"img_gif5.gif"
"/mnt/uda1/gif/2.gif"
};

/* image file path */
const char* app_ad_pic_png_item[] = 
{
"/mnt/uda1/png/1.png",
"/mnt/uda1/png/2.png",
"/mnt/uda1/png/3.png",
"/mnt/uda1/png/4.png",
"/mnt/uda1/png/5.png"
};
#else

/* image file path */
const char* app_ad_pic_jpg_item[] = {
"/mnt/uda1/jpg/1.jpg",
"/mnt/uda1/jpg/2.jpg",
"/mnt/uda1/jpg/3.jpg",
"/mnt/uda1/jpg/4.jpg",
"/mnt/uda1/jpg/5.jpg"
};

/* image file path */
const char* app_ad_pic_bmp_item[] = {
"/mnt/uda1/bmp/1.bmp",
"/mnt/uda1/bmp/2.bmp",
"/mnt/uda1/bmp/3.bmp",
"/mnt/uda1/bmp/4.bmp",
"/mnt/uda1/bmp/5.bmp"
};

/* image file path */
const char* app_ad_pic_gif_item[] =
{
"/mnt/uda1/gif/1.gif",
"/mnt/uda1/gif/2.gif",
"/mnt/uda1/gif/3.gif",
"/mnt/uda1/gif/4.gif",
"/mnt/uda1/gif/5.gif"
};

/* image file path */
const char* app_ad_pic_png_item[] = 
{
"/mnt/uda1/png/1.png",
"/mnt/uda1/png/2.png",
"/mnt/uda1/png/3.png",
"/mnt/uda1/png/4.png",
"/mnt/uda1/png/5.png"
};

#endif

const char** app_ad_pic_category[] =
{
    &app_ad_pic_jpg_item,
    &app_ad_pic_bmp_item,
    &app_ad_pic_gif_item,
    &app_ad_pic_png_item
};

const char* app_ad_pic_category_name[] =
{
    "category: JPEG ",
    "category: BMP",
    "category: GIF",
    "category: PNG"
};


char** app_ad_pic_path = &app_ad_pic_jpg_item;


typedef struct app_ad_pic_handle_tag{
    int category;
    int item;
    int select_new;
    int display;
} app_ad_pic_handle_t;

typedef struct app_ad_pic_op_tag {
    int (*decode) (app_ad_pic_data_t *ppic_img_data, const char* file_name);
    int (*display) (app_ad_pic_data_t *ppic_img_data);
    int (*undisplay) (app_ad_pic_data_t *ppic_img_data);
} app_ad_pic_op_t;

app_ad_pic_op_t app_ad_pic_op_simple = {
    app_ad_pic_decode,
    app_ad_pic_display,
    app_ad_pic_undisplay
};

app_ad_pic_handle_t      g_app_ad_pic_handle = {0, 0, 0, 0};
app_ad_pic_op_t         *g_app_ad_pic_op = NULL;
app_ad_pic_data_t        g_app_ad_pic_data;


#ifdef SUPPORT_AD_PIC_UIINFO
/* popup menu: show infomation */
static int app_ad_pic_popup_show(char *info)
{
    //return RET_SUCCESS;
    UINT8 back_save;
    win_compopup_smsg_restoreback();
    win_compopup_init(WIN_POPUP_TYPE_SMSG);
    
    win_compopup_set_msg(info, NULL, 0);
    win_compopup_set_frame(0, 320, 500, 100);
    win_compopup_open_ext(&back_save);
    return RET_SUCCESS;
}

/* popup menu: clean infomation */
static int app_ad_pic_popup_clean(UINT32 delay)
{
    //return RET_SUCCESS;
    osal_task_sleep(delay);
    win_compopup_smsg_restoreback();
    return RET_SUCCESS;
}
#else
static int app_ad_pic_popup_show(char *info)
{
    return RET_SUCCESS;
}
static int app_ad_pic_popup_clean(UINT32 delay)
{
    return RET_SUCCESS;
}
#endif


/* select the file category */
static int app_ad_pic_select_category()
{
    int mod = 4;

    g_app_ad_pic_handle.category++;
    g_app_ad_pic_handle.category %= mod;

    g_app_ad_pic_handle.item = 0;
    g_app_ad_pic_handle.select_new = 1;


    app_ad_pic_path = app_ad_pic_category[g_app_ad_pic_handle.category];

    app_ad_pic_popup_show(app_ad_pic_category_name[g_app_ad_pic_handle.category]);
    app_ad_pic_popup_clean(1000);

    return RET_SUCCESS;
}

/* select the file item */
static int app_ad_pic_select_item()
{
    int mod = 5;
    //mod = sizeof(app_ad_pic_path) / sizeof(const char*);
    char info[64];

    g_app_ad_pic_handle.item++;
    g_app_ad_pic_handle.item %= mod;
    g_app_ad_pic_handle.select_new = 1;

    AD_PIC_PRINTF("%s(): index=%d path=%s....\n", __FUNCTION__, g_app_ad_pic_handle.item, app_ad_pic_path[g_app_ad_pic_handle.item]);

    sprintf(info, "item: %s", app_ad_pic_path[g_app_ad_pic_handle.item]);

    app_ad_pic_popup_show(info);
    app_ad_pic_popup_clean(1000);
    return RET_SUCCESS;
}

/* display and undisplay the picture */
static int app_ad_pic_action()
{
    int ret = RET_SUCCESS;

    /* initialize the display/undisplay operation */
    if (NULL == g_app_ad_pic_op)
    {
        g_app_ad_pic_op=&app_ad_pic_op_simple;
    }

    /* when the osd is cleaned, just display the picture */
    if (FALSE == g_app_ad_pic_handle.display)
    {
        app_ad_pic_popup_show("waiting..");
        if (g_app_ad_pic_handle.category >= 2)
            app_ad_pic_popup_clean(0);
        ret = g_app_ad_pic_op->decode(&g_app_ad_pic_data, app_ad_pic_path[g_app_ad_pic_handle.item]);
        if (RET_SUCCESS != ret)
        {
            app_ad_pic_popup_show("ERROR!");
            app_ad_pic_popup_clean(1000);
            return ret;
        }
        if (g_app_ad_pic_handle.category < 2)
            app_ad_pic_popup_clean(0);
        ret = g_app_ad_pic_op->display(&g_app_ad_pic_data);
        if (RET_SUCCESS != ret)
        {
            app_ad_pic_popup_show("ERROR!");
            app_ad_pic_popup_clean(1000);
            return ret;
        }
        g_app_ad_pic_handle.select_new = 0;
        g_app_ad_pic_handle.display = TRUE;
        return RET_SUCCESS;
    }

    /* the picture is displayed. when other picture isn't selected, so undisplay and clear osd. */
    if (g_app_ad_pic_handle.select_new == 0)
    {
        app_ad_pic_popup_show("prepare to clear!");
        app_ad_pic_popup_clean(1000);
        ret = g_app_ad_pic_op->undisplay(&g_app_ad_pic_data);
        if (RET_SUCCESS != ret)
        {
            return ret;
        }
        g_app_ad_pic_handle.display = FALSE;
        return RET_SUCCESS;
    /* the picture is displayed. when other picture is selected, so display other picture. */
    } else {
        ret = g_app_ad_pic_op->undisplay(&g_app_ad_pic_data);
        if (RET_SUCCESS != ret)
        {
            return ret;
        }
        g_app_ad_pic_handle.display = FALSE;
        app_ad_pic_popup_show("waiting..");
        if (g_app_ad_pic_handle.category >= 2)
            app_ad_pic_popup_clean(0);
        ret = g_app_ad_pic_op->decode(&g_app_ad_pic_data, app_ad_pic_path[g_app_ad_pic_handle.item]);
        if (RET_SUCCESS != ret)
        {
            app_ad_pic_popup_show("ERROR!");
            app_ad_pic_popup_clean(1000);
            return ret;
        }
        if (g_app_ad_pic_handle.category < 2)
            app_ad_pic_popup_clean(0);
        ret = g_app_ad_pic_op->display(&g_app_ad_pic_data);
        if (RET_SUCCESS != ret)
        {
            app_ad_pic_popup_show("ERROR!");
            app_ad_pic_popup_clean(1000);
            return ret;
        }
        
        //g_app_ad_pic_handle.pre = g_app_ad_pic_handle.curr;
        g_app_ad_pic_handle.select_new = 0;
        g_app_ad_pic_handle.display = TRUE;
        return RET_SUCCESS;
    }

    return RET_SUCCESS;
}


/***************************************************************************************************
 * brief:     application, display the picture by using reference path. 
 * detail:    application, display the picture by using reference path. 
 * author:    robin.zhai
 *            saicheong.yuen
 * date:      2014-12-8
 ***************************************************************************************************/
#ifdef SUPPORT_AD_PIC_TIMER

#include "copper_common/com_api.h"

static void app_ad_pic_timer_select(void)
{
    static int item = 0;

    g_app_ad_pic_handle.category = 2;
    g_app_ad_pic_handle.item = item;
    g_app_ad_pic_handle.select_new = 1;
    app_ad_pic_path = app_ad_pic_category[g_app_ad_pic_handle.category];

    item++;
    item = (item % 2);
}

static void app_ad_pic_timer_event(UINT32 vkey)
{
    app_ad_pic_timer_select();

    UINT32 hkey;
	ap_vk_to_hk(0, V_KEY_MOVE, &hkey);
	ap_send_msg(CTRL_MSG_SUBTYPE_KEY, hkey, TRUE);
}

static int app_ad_pic_timer_onoff()
{
    static ID timer_id = OSAL_INVALID_ID;

    if (OSAL_INVALID_ID != timer_id)
    {
        osal_timer_activate(timer_id, TCY_OFF);

        if(OSAL_INVALID_ID != timer_id)
            osal_timer_delete(timer_id);

        timer_id = OSAL_INVALID_ID;

        UINT32 hkey;
    	ap_vk_to_hk(0, V_KEY_MOVE, &hkey);
    	ap_send_msg(CTRL_MSG_SUBTYPE_KEY, hkey, TRUE);
    }
    else
    {
        OSAL_T_CTIM  timer_data;

        MEMSET(&timer_data, 0, sizeof(OSAL_T_CTIM));
    	timer_data.callback = app_ad_pic_timer_event;
    	timer_data.type  = TIMER_CYCLIC;
    	timer_data.time  = 1000;
    	timer_data.param = 0;

        timer_id = osal_timer_create(&timer_data);

        if (OSAL_INVALID_ID == timer_id)
        {
             return RET_FAILURE;
        }

        osal_timer_activate(timer_id, TCY_ON);
    }

    return RET_SUCCESS;
}
#endif

static int app_ad_pic_initialized = 0;

void app_ad_pic_bufwarning()
{
    UINT8  back_save;
    char   info[256];
    UINT32 delay =  3000;

    INT32  buff_alloc_len = __MM_PVR_VOB_BUFFER_LEN;

    if (buff_alloc_len < 0x200000)
    {
        sprintf(info, "WARNNING!!! buffer too small!");
    }
    if (buff_alloc_len < 0x480000)
    {
        sprintf(info, "WARNNING!!! buffer limit!\nPNG GIF: <=400x300\n(PNG GIF)FILE SIZE: <= 1M\n\nPJPG:    no support!!\n");
    }
    else if (buff_alloc_len < 0x680000)
    {
        sprintf(info, "WARNNING!!! buffer limit!\nPNG GIF: <=800x600\n(PNG GIF)FILE SIZE: <= 1M\n\nPJPG:  may no support!!\n");
    }
    else
    {
        delay = 0;
    }

#ifndef ENABLE_PE_CACHE
    if (delay == 0)
        sprintf(info, "%sWARNNING!!!\n", info);

    sprintf(info, "%s(PJPG JPG BMP)FILE SIZE: <= 1M", info);
        delay = 1000;
#endif

    if (delay == 0)
    {
        return;
    }

    win_compopup_smsg_restoreback();
    win_compopup_init(WIN_POPUP_TYPE_SMSG);
    
    win_compopup_set_msg(info, NULL, 0);
    win_compopup_set_frame(0, 0, 600, 400);
    win_compopup_open_ext(&back_save);

    osal_task_sleep(delay);
    win_compopup_smsg_restoreback();
}

//Ben 150116#1	
int osd_test_show_flag(void)
{
	return g_app_ad_pic_handle.display;
}
//Ben 150116#1	

/* process key press!! */
int app_ad_pic_processkey(UINT32 vkey)
{
    int ret = RET_SUCCESS;

    switch(vkey)
    {
        case V_KEY_RED:
#if (SYS_SDRAM_SIZE == 64)
            app_ad_pic_bufwarning();
#endif
        case V_KEY_SWAP:
        case V_KEY_MOVE:
            /* initialize the display/undisplay operation */
            if (app_ad_pic_initialized == 0)
            {
                if (NULL == g_app_ad_pic_op)
                {
                    g_app_ad_pic_op=&app_ad_pic_op_simple;
                }
                ad_pic_bufmgr_init();
                if (vkey != V_KEY_RED)
                    app_ad_pic_bufwarning();
                app_ad_pic_initialized = 1;
            }
            break;
         default:
            break;
    }

    switch(vkey)
    {
        case V_KEY_RED:
            app_ad_pic_select_category();
            break;
        case V_KEY_SWAP:
            app_ad_pic_select_item();
            break;
        case V_KEY_MOVE:
    		//Ben 150116#1
		#ifdef SUPPORT_CAS7
		if(FALSE == g_app_ad_pic_handle.display)
			ShowBMailOSDOnOff(0);
		#endif
		//Ben 150116#1			
            app_ad_pic_action();
            break;
#ifdef SUPPORT_AD_PIC_TIMER
        case V_KEY_BLUE:
            app_ad_pic_timer_onoff();
            break;
#endif
        default:
            if (g_app_ad_pic_handle.display == TRUE)
            {
                if (NULL == g_app_ad_pic_op)
                {
                    return RET_FAILURE;
                }
                app_ad_pic_popup_show("prepare to clear!");
                app_ad_pic_popup_clean(1000);
                ret = g_app_ad_pic_op->undisplay(&g_app_ad_pic_data);
                if (RET_SUCCESS != ret)
                {
                    return ret;
                }
                g_app_ad_pic_handle.display = FALSE;
            }
            break;
    }
    return RET_SUCCESS;
}

#if 1
int ad_pic_jpegbmp_logoshow(UINT32 logo_id)
{
    RET_CODE ret_code = RET_FAILURE;
    UINT32   addr= 0;
    UINT32   len = 0;
    file_h   fh;
//    UINT8    *bitmap_buf;
//    INT32    bitmap_buflen;
    UINT8    *deccode_buf;
    INT32    deccode_buflen;
    UINT8    *fileoper_buf;
    INT32    fileoper_buflen;
    int      ret = RET_SUCCESS;
    BOOL     usbfile_filled = FALSE;

    struct sto_device *sto_flash_dev = NULL;
    CHUNK_HEADER chuck_hdr;

    ad_pic_bufmgr_init_logo();
    ad_pic_bufmgr_get_fileoperbuffer(&fileoper_buf, &fileoper_buflen);
    ad_pic_bufmgr_get_decodebuffer(&deccode_buf, &deccode_buflen);
//    ad_pic_bufmgr_get_picturebuffer(&bitmap_buf, &bitmap_buflen);

	#if 1
    //if ((g_app_ad_pic_handle.category == 0) && (g_app_ad_pic_handle.item != 0))
    if ((g_app_ad_pic_handle.category == 0) && (check_usb_item_is_active() == TRUE))
    {
        /* check if the usb inserted */
        if (check_usb_item_is_active() == FALSE)
        {
            AD_PIC_PRINTF("%s() : no usb!\n", __FUNCTION__);
        }
        else
        {
            FILE  *fp = NULL;
            fp = fopen(app_ad_pic_path[g_app_ad_pic_handle.item], "rb");
            len = fread(fileoper_buf, 1, fileoper_buflen, fp);
            AD_PIC_PRINTF("INFO: %s() read file:%s, len = %d\n", __FUNCTION__, app_ad_pic_path[g_app_ad_pic_handle.item], len);
            if ((len > 0) && (len < fileoper_buflen))
            {
                usbfile_filled = TRUE;
                osal_cache_flush(fileoper_buf, len);
            }
            fclose(fp);
        }
    }
	#endif
 
    AD_PIC_PRINTF("INFO: %s() using usb file!!\n", __FUNCTION__, usbfile_filled);

    if(usbfile_filled != TRUE)
    {
        if(0 == sto_get_chunk_header(logo_id, &chuck_hdr))
        {
            AD_PIC_PRINTF("%s() : flash error!\n", __FUNCTION__);
            return RET_FAILURE;
        }
        sto_flash_dev = (struct sto_device *)dev_get_by_id(HLD_DEV_TYPE_STO, 0);
        addr = (UINT32)sto_chunk_goto(&logo_id, 0xFFFFFFFF, 1) + CHUNK_HEADER_SIZE;
        len = chuck_hdr.len - CHUNK_HEADER_SIZE + CHUNK_NAME;

        sto_get_data(sto_flash_dev, (UINT8 *)fileoper_buf, addr, len);
        osal_cache_flush(fileoper_buf, len);         
    }

    ret = ad_pic_bufffile_init(&fh, fileoper_buf, len);
	if (ret != RET_SUCCESS)
    {
        return RET_FAILURE;
    }

    imagedec_id id = 0;

    /* initialize the decode buffer, and image file operations */
    Imagedec_Init_Config img_init_info;
    MEMSET(&img_init_info, 0, sizeof(Imagedec_Init_Config));

    img_init_info.frm_y_addr = __MM_FB0_Y_START_ADDR;
    img_init_info.frm_y_size = __MM_FB0_Y_LEN;
    img_init_info.frm_c_addr = __MM_FB0_C_START_ADDR;
    img_init_info.frm_c_size = __MM_FB0_C_LEN;

    img_init_info.frm2_y_addr = __MM_FB1_Y_START_ADDR;
    img_init_info.frm2_y_size = __MM_FB1_Y_LEN;
    img_init_info.frm2_c_addr = __MM_FB1_C_START_ADDR;
    img_init_info.frm2_c_size = __MM_FB1_C_LEN;


    img_init_info.decoder_buf = deccode_buf;
    img_init_info.decoder_buf_len = deccode_buflen;
    img_init_info.fread_callback = ad_pic_file_read;
    img_init_info.fseek_callback = ad_pic_file_seek;

    id = imagedec_init(&img_init_info);
    AD_PIC_PRINTF("%s() imagedec_init id = (%d)!\n", __FUNCTION__, id);
    if (0 == id)
    {
        AD_PIC_PRINTF("%s() imagedec_init failed(%d)!\n", __FUNCTION__, id);
        goto JPEG_LOGO_RELEASE;
    }

#ifdef DUAL_ENABLE
    imagedec_ioctl_ex(id, IMAGEDEC_IO_CMD_EXPAND, (UINT32)id);
#else
    imagedec_ioctl(id, IMAGEDEC_IO_CMD_EXPAND, (UINT32)id);
#endif
    /* configure the decode system. */
    Imagedec_Mode_Par dec_par;
    MEMSET((void *)&dec_par, 0, sizeof(Imagedec_Mode_Par));
    dec_par.vp_close_control = 0;
    dec_par.pro_show = 1;

    dec_par.dis_rect.uStartX = 0;
    dec_par.dis_rect.uStartY = 0;
    dec_par.dis_rect.uWidth = 720;
    dec_par.dis_rect.uHeight= 576;

    dec_par.src_rect.uStartX = 0;
    dec_par.src_rect.uStartY = 0;
    dec_par.src_rect.uWidth = 720;
    dec_par.src_rect.uHeight = 576;

    
    dec_par.show_mode = M_NORMAL;
    imagedec_set_mode(id, IMAGEDEC_FULL_SRN, &dec_par);

	//if(VIEW_MODE_PREVIEW == hde_get_mode())
    	vpo_win_onoff_ext((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS), FALSE, VPO_LAYER_MAIN);

    imagedec_de_config_imagetoplay();

    /* decode. */
    ret = imagedec_decode(id, fh);
    if (ret != TRUE)
        AD_PIC_PRINTF("\n Decode Image Unsuccessfully");

    imagedec_de_config_videotoplay();

#ifdef DUAL_ENABLE
    imagedec_ioctl_ex(id, IMAGEDEC_IO_CMD_EXPAND, (UINT32)NULL);
#else
    imagedec_ioctl(id, IMAGEDEC_IO_CMD_EXPAND, (UINT32)NULL);
#endif

#if 0
	if(VIEW_MODE_PREVIEW == hde_get_mode())
	{
	    struct Rect SrcRect;
	    struct Rect DstRect;

	    SrcRect.uStartX = 0;
	    SrcRect.uStartY = 0;
	    SrcRect.uWidth = 720;
	    SrcRect.uHeight = 576*5;
		hde_get_preview_win(&DstRect);
	    vpo_zoom((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS),&SrcRect,&DstRect);
	}
	vpo_win_onoff_ext((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS), TRUE, VPO_LAYER_MAIN);
#endif

JPEG_LOGO_RELEASE:
    /* recycle the resouce. */
    if (imagedec_stop(id) != TRUE)
        AD_PIC_PRINTF("\n Stop Image decoding unsuccessfully!\n");
    
    if (imagedec_release(id) != TRUE)
        AD_PIC_PRINTF("\n Release Image decoder unsuccessfully!\n");   

    ad_pic_bufffile_exit(fh);

    return ret;
}
#endif
#endif

